//
//  TimeStatisticsStore.swift
//  XingCeHelper
//
//  Created by 申铭 on 2022/10/14.
//

import Foundation
import CoreData

let kTimeStatistics = "TimeStatistics"

enum TimeStatisticsType: Int {
    case unknown = 0
    case xingce = 1000
    case ziliaofenxi = 1001
    case shipinjiexi = 1500
    case shenlunlianti = 2000
    case shenlun = 2001
    
    case calculate = 3000
    
    case reciteIdiom = 4000
    case reciteSpecification = 4500
    
    var description: String {
        switch self {
        case .xingce:
            return "行测模考"
        case .shipinjiexi:
            return "行测视频解析"
        case .ziliaofenxi:
            return "资料分析"
        case .shenlun:
            return "申论模考"
        case .shenlunlianti:
            return "申论练题"
        case .calculate:
            return "速算"
        case .reciteIdiom:
            return "背成语"
        case .reciteSpecification:
            return "背申论规范词"
        case .unknown:
            return "未知"
        }
    }
}

/// 时间戳 秒
@inline(__always) func FNowTime() -> TimeInterval {
    return NSDate().timeIntervalSince1970
}

class TimeStatisticsStore {
    
    /// 记录耗时
    /// - Parameters:
    ///   - duration: 持续时间
    ///   - type: 类型
    static func record(uuid: String, duration: TimeInterval, timer: CustomTimer) {
        let managedContext = CoreDataStack.shared.managedContext
        
//        for sta in query(type: .reciteIdiom) {
//            sta.timer = timer
//        }
        
        if let statistics = find(uuid: uuid) { // 有，改
            statistics.duration = duration
        } else {
            let statistics = NSEntityDescription.insertNewObject(forEntityName: kTimeStatistics, into: managedContext) as! TimeStatistics
            statistics.uuid = uuid
            statistics.duration = duration
            statistics.timer = timer
            statistics.recordTime = FNowTime()
        }
        
        do {
            try managedContext.save()
        } catch {
            print("错误：\(error)")
        }
    }
    
    /// 记录耗时
    /// - Parameters:
    ///   - duration: 持续时间
    ///   - type: 类型
    static func record(uuid: String, duration: TimeInterval, type: TimeStatisticsType) {
        let managedContext = CoreDataStack.shared.managedContext
        
        if let statistics = find(uuid: uuid) { // 有，改
            statistics.duration = duration
        } else {
            let statistics = NSEntityDescription.insertNewObject(forEntityName: kTimeStatistics, into: managedContext) as! TimeStatistics
            statistics.uuid = uuid
            statistics.duration = duration
            statistics.type = Int32(type.rawValue)
            statistics.recordTime = FNowTime()
        }
        
        do {
            try CoreDataStack.shared.managedContext.save()
        } catch {
            print("错误：\(error)")
        }
    }
    
    
    
    
    
//    /// 查询每组的耗时
//    /// select type,sum(统计列) from TABLE group by type
//    /// - Returns: arr
//    static func queryGroupDuration() -> Array<StatisticsModel> {
//        let fetchquest = NSFetchRequest<NSFetchRequestResult>(entityName: kTimeStatistics)
//
//        // 设置sum函数的字段
//        let type = NSExpression(forKeyPath:\TimeStatistics.duration)
//        let express = NSExpression(forFunction: "sum:", arguments: [type])
//        let expressDescription = NSExpressionDescription()
//        expressDescription.name = "sum"
//        expressDescription.expressionResultType = .doubleAttributeType
//        expressDescription.expression = express
//
//        fetchquest.propertiesToGroupBy = ["type"] // 分组字段
//        fetchquest.propertiesToFetch = ["type", expressDescription] // 结果字段
//        fetchquest.resultType = .dictionaryResultType // 结果范围类型
//
//        var arr = [StatisticsModel]()
//        do {
//            let results = try CoreDataStack.shared.managedContext.fetch(fetchquest)
//            for result in results  {
//                let dict = result as! Dictionary<String, TimeInterval>
//                var sta = StatisticsModel()
//                sta.type = Int(dict["type"] ?? 0)
//                sta.sum = dict["sum"] ?? 0
//                arr.append(sta)
//            }
//        } catch {
//            print("错误：\(error)")
//        }
//        return arr
//    }
    
    
    
    static func query(type: TimeStatisticsType) -> [TimeStatistics] {
        let managedContext = CoreDataStack.shared.managedContext
        let fetchRequest = NSFetchRequest<TimeStatistics>(entityName: kTimeStatistics)
        let predicate = NSPredicate(format: "type == %d", type.rawValue)
        fetchRequest.predicate = predicate

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects
        } catch {
            print("错误：\(error)")
        }
        
        return [TimeStatistics]()
    }
    
    // MARK: - 正式方法
    
    static func queryGroupDuration(start: TimeInterval, end: TimeInterval) -> Array<StatisticsModel> {
        let fetchquest = NSFetchRequest<NSFetchRequestResult>(entityName: kTimeStatistics)
        let predicate = NSPredicate(format: "recordTime > %lf AND recordTime < %lf", start, end) // 设置查询条件
        fetchquest.predicate = predicate
        
        // 设置sum函数的字段
        let type = NSExpression(forKeyPath:\TimeStatistics.duration)
        let express = NSExpression(forFunction: "sum:", arguments: [type])
        let expressDesc = NSExpressionDescription()
        expressDesc.name = "sum"
        expressDesc.expressionResultType = .doubleAttributeType
        expressDesc.expression = express
        
        let timerUUID = NSExpression(forKeyPath:\TimeStatistics.timer?.uuid)
        let timerUUIDDesc = NSExpressionDescription()
        timerUUIDDesc.name = "timerUUID"
        expressDesc.expressionResultType = .stringAttributeType
        timerUUIDDesc.expression = timerUUID
        
        fetchquest.propertiesToGroupBy = [timerUUIDDesc] // 分组字段
        fetchquest.propertiesToFetch = [timerUUIDDesc, expressDesc] // 结果字段
        fetchquest.resultType = .dictionaryResultType // 结果范围类型
        
        var arr = [StatisticsModel]()
        do {
            let results = try CoreDataStack.shared.managedContext.fetch(fetchquest)
            for result in results  {
                let dict = result as! Dictionary<String, String>
                var sta = StatisticsModel()
                sta.timerUUID = dict["timerUUID"]
                if let uuid = dict["timerUUID"] {
                    sta.customTimer = CustomTimerStore.find(uuid: uuid)
                }
                
                sta.sum = Double(dict["sum"] ?? "0") ?? 0
                arr.append(sta)
            }
        } catch {
            print("错误：\(error)")
        }
        return arr
    }
    
    /// 查询每组的耗时
    /// select type,sum(统计列) from TABLE group by type
    /// - Returns: Array<StatisticsModel>
    static func queryGroupDuration() -> Array<StatisticsModel> {
        let fetchquest = NSFetchRequest<NSFetchRequestResult>(entityName: kTimeStatistics)
        
        // 设置sum函数的字段
        let type = NSExpression(forKeyPath:\TimeStatistics.duration)
        let express = NSExpression(forFunction: "sum:", arguments: [type])
        let expressDesc = NSExpressionDescription()
        expressDesc.name = "sum"
        expressDesc.expressionResultType = .doubleAttributeType
        expressDesc.expression = express
        
        let timerUUID = NSExpression(forKeyPath:\TimeStatistics.timer?.uuid)
        let timerUUIDDesc = NSExpressionDescription()
        timerUUIDDesc.name = "timerUUID"
        expressDesc.expressionResultType = .stringAttributeType
        timerUUIDDesc.expression = timerUUID
        
        fetchquest.propertiesToGroupBy = [timerUUIDDesc] // 分组字段
        fetchquest.propertiesToFetch = [timerUUIDDesc, expressDesc] // 结果字段
        fetchquest.resultType = .dictionaryResultType // 结果范围类型
        
        var arr = [StatisticsModel]()
        do {
            let results = try CoreDataStack.shared.managedContext.fetch(fetchquest)
            for result in results  {
                let dict = result as! Dictionary<String, String>
                var sta = StatisticsModel()
                sta.timerUUID = dict["timerUUID"]
                if let uuid = dict["timerUUID"] {
                    sta.customTimer = CustomTimerStore.find(uuid: uuid)
                }
                
                sta.sum = Double(dict["sum"] ?? "0") ?? 0
                arr.append(sta)
            }
        } catch {
            print("错误：\(error)")
        }
        return arr
    }
    
    static func find(uuid: String) -> TimeStatistics? {
        let managedContext = CoreDataStack.shared.managedContext
        let fetchRequest = NSFetchRequest<TimeStatistics>(entityName: kTimeStatistics)
        let predicate = NSPredicate(format: "uuid == %@", uuid) // 设置查询条件
        fetchRequest.predicate = predicate

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects.first
        } catch {
            print("错误：\(error)")
        }
        
        return nil
    }
    
    /// 查询总计时
    /// - Returns: TimeInterval
    static func queryTotalTime() -> TimeInterval {
        let fetchquest = NSFetchRequest<NSFetchRequestResult>(entityName: kTimeStatistics)
        
        // 设置sum函数的字段
        let type = NSExpression(forKeyPath:\TimeStatistics.duration)
        let express = NSExpression(forFunction: "sum:", arguments: [type])
        let expressDescription = NSExpressionDescription()
        expressDescription.name = "sum"
        expressDescription.expressionResultType = .doubleAttributeType
        expressDescription.expression = express
        
        fetchquest.propertiesToFetch = [expressDescription] // 结果字段
        fetchquest.resultType = .dictionaryResultType // 结果范围类型
        
        do {
            let results = try CoreDataStack.shared.managedContext.fetch(fetchquest)
            for result in results  {
                let dict = result as! Dictionary<String, TimeInterval>
                return dict["sum"] ?? 0
            }
        } catch {
            print("错误：\(error)")
        }
        return 0
    }
    
}
